<?php

namespace App\Exceptions;

use ErrorException;
use Exception;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
use LogicException;
use ReflectionException;
use restful\ResultCode;
use restful\ResultException;
use restful\utils\Cipher;
use restful\utils\log\Log;
use RuntimeException;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;

class Handler extends ExceptionHandler
{
    protected $code = ResultCode::ERROR;
    protected $msg = '发生异常,请稍后重试~';
    protected $data;

    protected $httpCode = ResultCode::HTTP_ERROR_CODE;

    public function report(Exception $e)
    {}

    public function render($request, Exception $e)
    {
        // 设置响应数据
        $this->response($e);

        // 响应数据
        $response = [
            'code' => $this->code,
            'msg' => $this->msg,
            'data' => $this->data,
        ];
        // 响应处理
        $response = $this->responseHandler($request, $response);

        // 响应header
        $headers = [];

        // 判断刷新的token是否存在
        if(! empty($request->refreshToken)) {
            $headers['token'] = $request->refreshToken;
        }

        return response()->json($response, $this->httpCode, $headers, JSON_UNESCAPED_UNICODE);
    }

    protected function response(Exception $e)
    {
        if ($e instanceof ResultException) {
            // 返回异常
            $this->code = $e->getCode();
            $this->msg = $e->getMessage();
            $this->data = $e->getData();
            $this->httpCode = $e->getHttpCode();
        } elseif ($e instanceof MaintenanceModeException) {
            // 服务器维护中
            $this->code = ResultCode::MAINTENANCE;
            $this->msg = $e->getMessage() ?? '服务器维护中...';
        } elseif ($e instanceof HttpException) {
            // 请求异常
            $this->code = ResultCode::ERROR;
            $this->msg = '无效的请求!';
        } elseif ($e instanceof QueryException) {
            // 数据库异常
            $this->code = ResultCode::SYS_EXCEPTION;
            $this->msg = '发生异常,请稍后重试~';
            Log::save('handle_db.exception', $e->getMessage() . PHP_EOL . $e->getTraceAsString());
        } elseif ($e instanceof ReflectionException || $e instanceof LogicException || $e instanceof RuntimeException) {
            // 发生异常
            $this->code = ResultCode::SYS_EXCEPTION;
            $this->msg = '发生异常,请稍后重试~';
            Log::save('handle.exception', $e->getMessage() . PHP_EOL . $e->getTraceAsString());
        } elseif ($e instanceof FatalThrowableError || $e instanceof ErrorException) {
            // 发生错误
            $this->code = ResultCode::SYS_ERROR;
            $this->msg = '发生错误,请稍后重试~';
            Log::save('handle.error', $e->getMessage() . PHP_EOL . $e->getTraceAsString());
        }
    }

    /**
     * 响应处理
     * @param $request
     * @param array $response
     * @return array|string
     */
    protected function responseHandler($request, array $response)
    {
        try {
            $response = Cipher::response($request, $response);
        } catch (Throwable $e) {}

        return $response;
    }
}
